package com.authine.cloudpivot.ext.controller;

import com.alibaba.fastjson.JSONObject;
import com.authine.cloudpivot.engine.api.model.organization.UserModel;
import com.authine.cloudpivot.engine.api.model.runtime.BizObjectCreatedModel;
import com.authine.cloudpivot.engine.api.model.runtime.WorkItemModel;
import com.authine.cloudpivot.engine.api.model.runtime.WorkflowInstanceModel;
import com.authine.cloudpivot.engine.enums.status.SequenceStatus;
import com.authine.cloudpivot.ext.Utils.CustomSchemaCode;
import com.authine.cloudpivot.ext.service.CloudSqlService;
import com.authine.cloudpivot.web.api.controller.base.BaseController;
import com.authine.cloudpivot.web.api.view.ResponseResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 加油记录
 */
@Slf4j
@RestController
@RequestMapping("/public/RefuelRecordController")
public class RefuelRecordController extends BaseController {

    @Autowired
    private AttributeController attributeController;

    @Autowired
    CloudSqlService sqlService;

    /**
     * 查询加油对象的上一次最新里程
     *
     * @param jydx
     */
    @GetMapping("/getLatestMileage")
    public ResponseResult<Map<String, Object>> getLatestMileage(String jydx) {
        String tableName = getBizObjectFacade().getTableName(CustomSchemaCode.refuelRecordDetai);
        StringBuffer sql = new StringBuffer("select mileage from ").append(tableName).append(" where refuelingObjectCode = '")
                .append(jydx).append("' ORDER BY mileage desc limit 1");
        Map<String, Object> map = sqlService.getMap(sql.toString());
        return getOkResponseResult(map, "success");
    }

    /**
     * 加油记录  审批流完成后 数据写到-油卡信息记录 基础表，补全基础表的数据
     */
    @RequestMapping("finish")
    public void finish(String bizId) {

        BizObjectCreatedModel bizObject = getBizObjectFacade().getBizObject(CustomSchemaCode.refuelRecord, bizId);
        List<Map<String, Object>> list = (List<Map<String, Object>>) bizObject.get(CustomSchemaCode.refuelRecordDetai);
        String now = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        String approval = getFileBaseInfoWorkFlowApproval(bizObject);
        for (Map<String, Object> map : list) {

            try {
                Map<String, Object> data = fileInfoBaseMap(map, now, approval);
                //将子表中数据处理，随后更新至【加油记录 基础表】，需要判断是否存在
                String id = existsBizObject(map);
                if (StringUtils.isNotBlank(id)) {
                    data.put("id", id);
                }

                BizObjectCreatedModel model = new BizObjectCreatedModel(CustomSchemaCode.refuelRecordBase, data, false);
                model.setSequenceStatus(SequenceStatus.COMPLETED.name());
                id = getBizObjectFacade().saveBizObject(CustomSchemaCode.adminUserId, model, false);
                log.info("油卡信息记录-新增成功 ");
                //调用存储过程
                callProcess(id);

            } catch (Exception e) {
                log.info("油卡信息记录-操作失败");
                log.info(e.getMessage(), e);
            }

        }
    }

    @RequestMapping("toVoid")
    public void toVoid(String bizId) {
        log.info("加油记录toVoid");
//        BizObjectCreatedModel bizObject = getBizObjectFacade().getBizObject(CustomSchemaCode.voidOilCarInformationRecord, bizId);
//        List<Map<String, Object>> list = (List<Map<String, Object>>) bizObject.get(CustomSchemaCode.voidOilCarInformationRecordDetail);
//        String now = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
//        //获取审批人
//        String approval = getFileBaseInfoWorkFlowApproval(bizObject);
//        for (Map<String, Object> map : list) {
//            try {
//                String id = existsBizObject(map);
//                //判断是否已存在，如果不存在，放弃这条数据，直接跳过此次循环
//                if (StringUtils.isBlank(id)) {
//                    continue;
//                }
//
//                //获取数据
//                Map<String, Object> data = fileInfoBaseMap(map, now, approval);
//                data.put("id", id);
//
//                BizObjectCreatedModel model = new BizObjectCreatedModel(CustomSchemaCode.oilCarInformationBasic, data, false);
//                model.setSequenceStatus(SequenceStatus.CANCELED.name());
//                id = getBizObjectFacade().saveBizObject(CustomSchemaCode.adminUserId, model, false);
//                log.info("加油记录基础表  作废操作成功 ");
//                //调用存储过程
////                callProcessToVoid(id);
//
//            } catch (Exception e) {
//                log.info("加油记录基础表-操作失败");
//                log.info(e.getMessage(), e);
//            }
//
//        }
    }

    /**
     * 查询审批人,返回  员工号+姓名
     *
     * @param bizObject
     * @return
     */
    private String getFileBaseInfoWorkFlowApproval(BizObjectCreatedModel bizObject) {
        WorkflowInstanceModel instanceModel = getWorkflowInstanceFacade().getByObjectId(bizObject.getId());
        List<WorkItemModel> workItems = getWorkflowInstanceFacade().getWorkItems(instanceModel.getId(), true);
        final String finalActivityCode = "Activity24";
        Optional<WorkItemModel> first = workItems.stream().filter(a -> a.getActivityCode().equals(finalActivityCode)).findFirst();
        String participant = null;
        if (first.isPresent()) {
            WorkItemModel workItemModel = first.get();
            participant = workItemModel.getParticipant();
        }

        if (participant == null) {
            final String finalActivityCode2 = "Activity20";
            Optional<WorkItemModel> second = workItems.stream().filter(a -> a.getActivityCode().equals(finalActivityCode2)).findFirst();
            if (second.isPresent()) {
                WorkItemModel workItemModel = second.get();
                participant = workItemModel.getParticipant();
            }
        }


        if (participant == null) {
            participant = bizObject.getCreater().getId();
        }

        UserModel user = getOrganizationFacade().getUser(participant);


        return new StringBuilder(user.getEmployeeNo()).append("　").append(user.getName()).toString();
    }


    /**
     * 判断是否已存在
     *
     * @return
     */
    private String existsBizObject(Map data) {

        //卡号
        String cardNumber = (String) data.get("cardNumber");

        String tableName = getBizObjectFacade().getTableName(CustomSchemaCode.refuelRecordBase);

        StringBuilder sql = new StringBuilder("select id  from ").append(tableName).append(" where cardNumber ='").append(cardNumber).append("'");

        Map<String, Object> map = sqlService.getMap(sql.toString());

        return (String) map.get("id");
    }

    /**
     * 转换成  加油记录 基础表 的数据
     *
     * @param map
     * @param auditDate
     * @return
     */
    private Map<String, Object> fileInfoBaseMap(Map<String, Object> map, String auditDate, String approval) {
        Map<String, Object> data = new HashMap<>();
        data.put("company_OilCard", map.get("company_OilCard"));
        data.put("companyNumber_OilCard", map.get("companyNumber_OilCard"));
        data.put("companyName_OilCard", map.get("companyName_OilCard"));
        data.put("cardNumber", map.get("cardNumber"));
        data.put("cardNumberFid", map.get("cardNumberFid"));
        data.put("cardNumber2", map.get("cardNumber2"));
        data.put("managementDeptFid", map.get("managementDeptFid"));
        data.put("managementDeptFNumber", map.get("managementDeptFNumber"));
        data.put("managementDeptName", map.get("managementDeptName"));
        data.put("relevancePostA", map.get("relevancePostA"));
        data.put("postANumber", map.get("postANumber"));
        data.put("postAName", map.get("postAName"));
        data.put("relevancePostB", map.get("relevancePostB"));
        data.put("postBNumber", map.get("postBNumber"));
        data.put("postBName", map.get("postBName"));
        data.put("oilCardRecordNumber", map.get("oilCardRecordNumber"));
        data.put("oilCardRecordNumberText", map.get("oilCardRecordNumberText"));
        data.put("refuelingDate", map.get("refuelingDate"));
        data.put("dosage", map.get("dosage"));
        data.put("oilVariety", map.get("oilVariety"));
        data.put("amount", map.get("amount"));
        data.put("refuelingCompany", map.get("refuelingCompany"));
        data.put("refuelingCompanyFNumber", map.get("refuelingCompanyFNumber"));
        data.put("refuelingCompanyName", map.get("refuelingCompanyName"));
        data.put("adminDeptFid", map.get("adminDeptFid"));
        data.put("adminDeptFNumber", map.get("adminDeptFNumber"));
        data.put("adminDeptName", map.get("adminDeptName"));
        data.put("refuelingDept", map.get("refuelingDept"));
        data.put("refuelingDeptFNumber", map.get("refuelingDeptFNumber"));
        data.put("refuelingPersonnel", map.get("refuelingPersonnel"));
        data.put("refuelingPersonnelName", map.get("refuelingPersonnelName"));
        data.put("refuelingObjectCode", map.get("refuelingObjectCode"));
        data.put("refuelingObject", map.get("refuelingObject"));
        data.put("car_manageDeptFid", map.get("car_manageDeptFid"));
        data.put("car_manageDeptFNumber", map.get("car_manageDeptFNumber"));
        data.put("managePostA", map.get("managePostA"));
        data.put("managePostAFNumber", map.get("managePostAFNumber"));
        data.put("managePostB", map.get("managePostB"));
        data.put("managePostBFNumber", map.get("managePostBFNumber"));
        data.put("mileage", map.get("mileage"));
        data.put("interval", map.get("interval"));
        data.put("description", map.get("description"));
        //审批人
        data.put("approval", approval);
        //审批时间
        data.put("auditDate", auditDate);
        return data;
    }

    /**
     * ----加油记录
     * exec    SyncFeulUpRecord
     *
     * @comid nvarchar(100),            ----公司id
     * @CardNum nvarchar(100),            ----油卡卡号
     * @RecordNum nvarchar(100),            ----记录号
     * @AddDate datetime,                ----加油日期
     * @Qty decimal(16, 6),            ----用量
     * @oiltype nvarchar(100),            ----油品
     * @Amount decimal(10, 2),            ----金额
     * @UseComid nvarchar(100),            ----加油公司ID
     * @UseDeptid nvarchar(100),            ----加油部门
     * @PersonCode nvarchar(100),            ----人员代码
     * @CarNum nvarchar(100),            ----加油对象
     * @MailAge decimal(10, 2),            ----里程
     * @InterVal decimal(10, 2),            ----间隔
     * @WorkDesc nvarchar(255),            ----工作说明
     * @Auditor nvarchar(100)            ----审批人
     */
    private void callProcess(String bizId) {

        if (StringUtils.isEmpty(bizId)) {
            return;
        }
        //编写sql
        String tableName = getBizObjectFacade().getTableName(CustomSchemaCode.refuelRecordBase);
        StringBuilder sql = new StringBuilder("SELECT * from ")
                .append(tableName).append(" where id ='")
                .append(bizId).append("';");
        //查询到入参
        Map<String, Object> map = sqlService.getMap(sql.toString());
        log.info("入参map={}", JSONObject.toJSONString(map));

        //调用存储过程
        String company_OilCard = MapUtils.getString(map, "company_OilCard", "");
        String cardNumber = MapUtils.getString(map, "cardNumber", "");
        String oilCardRecordNumberText = MapUtils.getString(map, "oilCardRecordNumberText", "");

//        Date refuelingDateTemp = (Date) map.get("refuelingDate");
//        String refuelingDate = refuelingDateTemp == null ? "" : DateFormatUtils.format(refuelingDateTemp, "yyyy-MM-dd");
        LocalDateTime refuelingDateTemp = (LocalDateTime) map.get("refuelingDate");
        String refuelingDate =  ObjectUtils.isEmpty(refuelingDateTemp) ? "" : refuelingDateTemp.toLocalDate().toString();

        String dosage = MapUtils.getString(map, "dosage", "");
        String oilVariety = MapUtils.getString(map, "oilVariety", "");
        String amount = MapUtils.getString(map, "amount", "");
        String refuelingCompany = MapUtils.getString(map, "refuelingCompany", "");
        String refuelingDept = MapUtils.getString(map, "refuelingDept", "");
        String refuelingPersonnel = MapUtils.getString(map, "refuelingPersonnel", "");//人员代码
        String refuelingObjectCode = MapUtils.getString(map, "refuelingObjectCode", "");
        String mileage = MapUtils.getString(map, "mileage", "");
        String interval = MapUtils.getString(map, "interval", "");
        String description = MapUtils.getString(map, "description", "");
        String approval = MapUtils.getString(map, "approval", "");//审批人   02.0100 张三

        String execSql = String.format("exec [HG_LINK].[hg].[dbo].SyncFeulUpRecord '%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s'",
                company_OilCard, cardNumber, oilCardRecordNumberText, refuelingDate, dosage, oilVariety,
                amount, refuelingCompany, refuelingDept, refuelingPersonnel, refuelingObjectCode, mileage,
                interval, description, approval);
        log.info("\n==========准备调用[加油记录]存储过程:{}", execSql);
        sqlService.execute(CloudSqlService.htEas, execSql);
        log.info("\n=============[加油记录]存储过程执行完成");
    }

    /**
     * ----场地信息记录   作废
     * exec   SiteInfoDisable
     *
     * @SiteCode nvarchar(100)     ----场地代码
     */
    private void callProcessToVoid(String bizId) {

        if (StringUtils.isEmpty(bizId)) {
            return;
        }
        //编写sql
        String tableName = getBizObjectFacade().getTableName(CustomSchemaCode.oilCarInformationBasic);
        StringBuilder sql = new StringBuilder("SELECT * from ")
                .append(tableName).append(" where id ='")
                .append(bizId).append("';");
        //查询到入参
        Map<String, Object> map = sqlService.getMap(sql.toString());
        log.info("入参map={}", map);

        //准备调用存储过程的入参
        String placeCode = MapUtils.getString(map, "placeCode", "");//fid
        String execSql = String.format("exec [HG_LINK].[hg].[dbo].SiteInfoDisable '%s'", placeCode);
        log.info("\n==========准备调用[加油记录   作废]存储过程:{}", execSql);
        sqlService.execute(CloudSqlService.htEas, execSql);
        log.info("\n=============[加油记录   作废]存储过程执行完成");

    }

}
